import { parse } from 'qs';
import { login, userInfo, logout } from 'src/services/frame';
import { crumbMap } from 'src/utils/constants';
import _ from 'underscore';

function* getCrumbItem(flattenMap, pathname) {
  if (flattenMap[pathname]) {
    let { key, name, parent, path } = flattenMap[pathname];
    yield { key, name, path };
    yield* getCrumbItem(flattenMap, parent);
  }
}

function* flatCrumb(data, parent, query) {
  let { key, name, child, parameterKey } = data;
  let path = key;
  if (query && parameterKey && query[parameterKey]) {
    path += '?' + parameterKey + '=' + query[parameterKey];
  }
  yield { key, name, parent, path };

  if (child) {
    for (let i = 0; i < child.length; i++) {
      yield* flatCrumb(child[i], key, query);
    }
  }
}

function parseCrumb({ pathname, query }) {
  let flattenMap = {};
  for (let flattenItem of flatCrumb(crumbMap, 0, query)) {
    flattenMap[flattenItem.key] = flattenItem;
  }
  let crumbList = [];
  for (let crumbItem of getCrumbItem(flattenMap, pathname)) {
    crumbList.push(crumbItem);
  }
  return crumbList.reverse();
}

export default {
  namespace: 'frame',
  state: {
    login: false,
    userName: '',
    userId: '',
    containerClass: 'layout-container',
    crumbList: [],
    header: {
      className: '',
      current: ''
    },
  },
  subscriptions: {
    setup({ dispatch, history }) {
      dispatch({ type: 'getUser' });

      history.listen(({ pathname, query }) => {
        dispatch({
          type: 'pathChange',
          payload: { pathname, query },
        });
      });
    },
  },
  effects: {
    * getUser({}, { call, put }) {
      const { data } = yield call(userInfo);
      if (data) {
        yield put({
          type: 'loginSuccess',
          payload: { ...data },
        });
      }
    },

    * logout({
      payload,
    }, { call, put }) {
      const data = yield call(logout, parse(payload));
      if (data.success) {
        yield put({
          type: 'logoutSuccess',
        });
        yield put({
          type: 'getUser',
        });
      }
    },
  },
  reducers: {

    pathChange(state, action) {
      const crumbDataList = parseCrumb(action.payload);
      return {
        ...state,
        crumbList: crumbDataList,
      };
    },

    loginSuccess(state, action) {
      return {
        ...state,
        ...action.payload,
        login: true,
      };
    },

    navSelect(state, action) {
      return {
        ...state,
        header: {
          ...state.header,
          current: action.payload,
        },
      };
    },
  },
};
